package com.lh0811.forge.pserv.uacs.server.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lh0811.forge.dependency.basic_code.BeanHelper;
import com.lh0811.forge.dependency.basic_code.IdWorker;
import com.lh0811.forge.dependency.basic_web.exception.CommonException;
import com.lh0811.forge.dependency.basic_web.response.ServerResponse;
import com.lh0811.forge.dependency.security.client.component.SecurityUtil;
import com.lh0811.forge.dependency.security.core.model.entity.SecurityAuthority;
import com.lh0811.forge.pserv.uacs.api.component.data_scope.DataScope;
import com.lh0811.forge.pserv.uacs.api.param.UacsDataRuleCreateParam;
import com.lh0811.forge.pserv.uacs.api.param.UacsDataRuleQueryListParam;
import com.lh0811.forge.pserv.uacs.api.param.UacsDataRuleQueryPageParam;
import com.lh0811.forge.pserv.uacs.api.param.UacsDataRuleUpdateParam;
import com.lh0811.forge.pserv.uacs.api.vo.UacsDataRuleVo;
import com.lh0811.forge.pserv.uacs.server.component.data_scope.constant.RuleLogicEnum;
import com.lh0811.forge.pserv.uacs.server.component.data_scope.constant.RuleValueSourceEnum;
import com.lh0811.forge.pserv.uacs.server.repository.dao.UacsDataRuleDao;
import com.lh0811.forge.pserv.uacs.server.repository.dao.UacsTenantPostDataRuleRefDao;
import com.lh0811.forge.pserv.uacs.server.repository.entity.UacsDataRule;
import com.lh0811.forge.pserv.uacs.server.repository.entity.UacsTenantPostDataRuleRef;
import com.lh0811.forge.pserv.uacs.server.service.PlateDataRuleService;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PlateDataRuleServiceImpl implements PlateDataRuleService {

    @Resource
    private UacsDataRuleDao uacsDataRuleDao;

    @Resource
    private UacsTenantPostDataRuleRefDao uacsTenantPostDataRuleRefDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dataRuleCreate(UacsDataRuleCreateParam param) throws Exception {
        // 获取当前登录用户
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();

        // 判断数据规则是否已经存在
        Long dataRuleSize = uacsDataRuleDao.lambdaQuery()
                .eq(UacsDataRule::getDataTable, param.getDataTable())
                .eq(UacsDataRule::getDataDimension, param.getDataDimension())
                .eq(UacsDataRule::getRuleLogic, param.getRuleLogic())
                .count();
        if (dataRuleSize > 1) {
            throw CommonException.create(ServerResponse.createByError(param.getDataTable() + "." + param.getDataDimension() + ":" + param.getRuleLogic() + " 数据规则已存在"));
        }

        // 新增数据规则
        UacsDataRule uacsDataRule = new UacsDataRule();

        uacsDataRule.setId(IdWorker.nextId()); // "主键
        uacsDataRule.setDataTable(param.getDataTable()); // "数据表
        uacsDataRule.setDataTableName(param.getDataTableName()); // "数据表名称
        uacsDataRule.setDataDimension(param.getDataDimension()); // "数据表维度字段
        uacsDataRule.setDataDimensionName(param.getDataDimensionName()); // "数据表维度字段名称
        uacsDataRule.setRuleLogic(param.getRuleLogic()); // "规则逻辑：1-等于 2-不等于 3-大于 4-小于 5-大于等于 6-小于等于 7-包含 8-不包含 9-在列表中 10-不在列表中
        uacsDataRule.setRuleValueSource(param.getRuleValueSource()); // "逻辑值来源： 1-后台维护 2-系统数据源 3-系统提供
        uacsDataRule.setRuleValue(param.getRuleValue()); // "逻辑值
        uacsDataRule.setRuleSourceUrl(param.getRuleSourceUrl()); // "获取数据源列表的URL
        uacsDataRule.setRuleValueProvider(param.getRuleValueProvider()); // "系统数据值提供器全类名
        uacsDataRule.setValueType(param.getValueType()); // "1-字符串 2-数字
        uacsDataRule.setValueStruct(param.getValueStruct()); // "1-单值 2-列表 3-字典
        uacsDataRule.setNotes(param.getNotes()); // "备注
        uacsDataRule.setCreateTime(new Date()); // "创建时间
        uacsDataRule.setCreateBy(Long.valueOf(securityAuthority.getUserId())); // "创建人

        String dataRuleName = uacsDataRule.getDataTableName() + "." + uacsDataRule.getDataDimensionName() + "[" + RuleLogicEnum.getByCode(uacsDataRule.getRuleLogic()) + "]";
        if (StringUtils.equals(uacsDataRule.getRuleValueSource(), RuleValueSourceEnum.后台维护.getCode())) {
            dataRuleName = dataRuleName + "(" + uacsDataRule.getRuleValue() + ")";
        } else if (StringUtils.equals(uacsDataRule.getRuleValueSource(), RuleValueSourceEnum.系统数据源.getCode())) {
            dataRuleName = dataRuleName + "(数据源:" + uacsDataRule.getRuleSourceUrl() + ")";
        } else if (StringUtils.equals(uacsDataRule.getRuleValueSource(), RuleValueSourceEnum.系统提供.getCode())) {
            dataRuleName = dataRuleName + "(系统提供:" + uacsDataRule.getRuleValueProvider() + ")";
        }
        uacsDataRule.setDataRuleName(dataRuleName);

        uacsDataRuleDao.save(uacsDataRule);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dataRuleDelete(Long dataRuleId) throws Exception {
        // 判断数据规则是否存在
        UacsDataRule dataRule = uacsDataRuleDao.getById(dataRuleId);
        if (ObjectUtils.isEmpty(dataRule)) {
            throw CommonException.create(ServerResponse.createByError("数据规则不存在"));
        }

        // 移除岗位的数据关联
        List<UacsTenantPostDataRuleRef> dataRuleRefList = uacsTenantPostDataRuleRefDao.lambdaQuery().eq(UacsTenantPostDataRuleRef::getDataRuleId, dataRuleId).list();
        if (CollectionUtils.isNotEmpty(dataRuleRefList)) {
            uacsTenantPostDataRuleRefDao.removeByIds(dataRuleRefList.stream().map(ele -> ele.getId()).collect(Collectors.toList()));
        }

        // 移除数据规则
        uacsDataRuleDao.removeById(dataRuleId);
    }

    // 修改数据规则
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dataRuleUpdate(UacsDataRuleUpdateParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        // 判断数据规则是否存在
        UacsDataRule dataRule = uacsDataRuleDao.getById(param.getId());
        if (ObjectUtils.isEmpty(dataRule)) {
            throw CommonException.create(ServerResponse.createByError("数据规则不存在"));
        }

        // 是否修改数据规则 三元素
        if (!StringUtils.equals(dataRule.getRuleLogic(), param.getRuleLogic()) || !StringUtils.equals(dataRule.getDataTable(), param.getDataTable()) || !StringUtils.equals(dataRule.getDataDimension(), param.getDataDimension())) {
            // 判断数据规则是否已经存在
            Long dataRuleSize = uacsDataRuleDao.lambdaQuery()
                    .eq(UacsDataRule::getDataTable, param.getDataTable())
                    .eq(UacsDataRule::getDataDimension, param.getDataDimension())
                    .eq(UacsDataRule::getRuleLogic, param.getRuleLogic())
                    .count();
            if (dataRuleSize > 1) {
                throw CommonException.create(ServerResponse.createByError(param.getDataTable() + "." + param.getDataDimension() + ":" + param.getRuleLogic() + " 数据规则已存在"));
            }
        }

        // 修改数据
        UacsDataRule updateInfo = BeanHelper.copyBean(param, UacsDataRule.class);
        updateInfo.setUpdateBy(Long.valueOf(securityAuthority.getUserId()));
        updateInfo.setUpdateTime(new Date());
        uacsDataRuleDao.updateById(updateInfo);

        UacsDataRule uacsDataRule = uacsDataRuleDao.getById(dataRule.getId());
        String dataRuleName = uacsDataRule.getDataTableName() + "." + uacsDataRule.getDataDimensionName() + "[" + RuleLogicEnum.getByCode(uacsDataRule.getRuleLogic()) + "]";
        if (StringUtils.equals(uacsDataRule.getRuleValueSource(), RuleValueSourceEnum.后台维护.getCode())) {
            dataRuleName = dataRuleName + "(" + uacsDataRule.getRuleValue() + ")";
        } else if (StringUtils.equals(uacsDataRule.getRuleValueSource(), RuleValueSourceEnum.系统数据源.getCode())) {
            dataRuleName = dataRuleName + "(数据源:" + uacsDataRule.getRuleSourceUrl() + ")";
        } else if (StringUtils.equals(uacsDataRule.getRuleValueSource(), RuleValueSourceEnum.系统提供.getCode())) {
            dataRuleName = dataRuleName + "(系统提供:" + uacsDataRule.getRuleValueProvider() + ")";
        }
        uacsDataRule.setDataRuleName(dataRuleName);
        uacsDataRuleDao.lambdaUpdate().set(UacsDataRule::getDataRuleName, dataRuleName).eq(UacsDataRule::getId, uacsDataRule.getId()).update();
    }

    // 查询数据规则(分页)
    @Override
    @DataScope
    public PageInfo<UacsDataRuleVo> dataRuleQueryPage(UacsDataRuleQueryPageParam param) throws Exception {
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<UacsDataRule> list = uacsDataRuleDao.lambdaQuery()
                .eq(StringUtils.isNotBlank(param.getDataTable()), UacsDataRule::getDataTable, param.getDataTable())
                .eq(StringUtils.isNotBlank(param.getDataDimension()), UacsDataRule::getDataDimension, param.getDataDimension())
                .eq(StringUtils.isNotBlank(param.getRuleLogic()), UacsDataRule::getRuleLogic, param.getRuleLogic())
                .eq(StringUtils.isNotBlank(param.getRuleValueSource()), UacsDataRule::getRuleValueSource, param.getRuleValueSource())
                .orderByDesc(UacsDataRule::getCreateTime)
                .list();
        PageInfo pageInfo = new PageInfo<>(list);
        PageHelper.clearPage();
        pageInfo.setList(BeanHelper.copyList(pageInfo.getList(), UacsDataRuleVo.class));
        return pageInfo;
    }

    // 查询数据规则(不分页)
    @Override
    @DataScope
    public List<UacsDataRuleVo> dataRuleQueryList(UacsDataRuleQueryListParam param) throws Exception {
        List<UacsDataRule> list = uacsDataRuleDao.lambdaQuery()
                .eq(StringUtils.isNotBlank(param.getDataTable()), UacsDataRule::getDataTable, param.getDataTable())
                .eq(StringUtils.isNotBlank(param.getDataDimension()), UacsDataRule::getDataDimension, param.getDataDimension())
                .eq(StringUtils.isNotBlank(param.getRuleLogic()), UacsDataRule::getRuleLogic, param.getRuleLogic())
                .eq(StringUtils.isNotBlank(param.getRuleValueSource()), UacsDataRule::getRuleValueSource, param.getRuleValueSource())
                .orderByDesc(UacsDataRule::getCreateTime)
                .list();
        return BeanHelper.copyList(list, UacsDataRuleVo.class);
    }


}
